<template>
  <el-dialog
    :title="title"
    width="500px"
    @open="handleOpen"
    @close="handleClose"
  >
    <el-form
      :model="form"
      :rules="rules"
      label-width="100px"
      class="edit-add-form"
      ref="formRef"
    >
      <el-form-item label="角色名称" prop="roleName">
        <el-input :disabled="roleNameDisabled" v-model="form.roleName" />
      </el-form-item>
      <el-form-item label="备注" prop="remark">
        <el-input v-model="form.remark" />
      </el-form-item>
      <el-form-item label="菜单权限" prop="menuIds">
        <el-tree
          ref="menuTreeRef"
          :data="data"
          show-checkbox
          node-key="id"
          :props="defaultProps"
          @check-change="handleMenuChange"
        >
        </el-tree>
      </el-form-item>
    </el-form>
    <template #footer>
      <el-button @click="handleCancel">取消</el-button>
      <el-button type="primary" @click="handleConfirm(formRef!)"
        >确认</el-button
      >
    </template>
  </el-dialog>
</template>
<script lang="ts" setup>
// import { addEditDialog } from "@/composition/addEditDialog";
import { EditForm } from "../types";
import { usePermissionStore } from "store/modules/permission";
import { ElTree } from "element-plus";
import { cloneDeep } from "lodash";
import { requiredValidate, lengthValidate } from "utils/validate";
import type { FormInstance, FormRules } from "element-plus";

interface Props {
  flag?: "edit" | "add";
  formData?: EditForm;
}
const props = withDefaults(defineProps<Props>(), {
  flag: "edit",
});

interface DefineEmits {
  (e: "handleConfirm", formData: EditForm): void; // 自定义事件
  (e: "handleClose"): void; // 自定义事件
  (e: "update:modelValue", visible: boolean): void;
}
const emits = defineEmits<DefineEmits>();

const formRef = ref<FormInstance>();
const checkMenuIds = (rule: any, value: any, callback: any) => {
  if (value.length === 0) {
    callback(new Error("必填"));
  } else {
    callback();
  }
};
const rules = reactive<FormRules>({
  roleName: [requiredValidate(), lengthValidate(10)],
  remark: [requiredValidate(), lengthValidate(20)],
  menuIds: [requiredValidate(), { validator: checkMenuIds, trigger: "change" }],
});

const initForm: EditForm = {
  roleName: "",
  remark: "",
  menuIds: [],
};

const form = ref<EditForm>(cloneDeep(initForm));

const title = computed(() => (props.flag === "edit" ? "编辑" : "新增"));

const roleNameDisabled = computed<boolean>(() => props.flag === "edit");

const defaultProps = {
  children: "children",
  label: "text",
};

// menu tree
const permissionStore = usePermissionStore();
const data = computed(() => permissionStore.menuList);

// update menu tree
const menuTreeRef = ref<InstanceType<typeof ElTree>>();

const setCheckedKeys = (keys: number[]) => {
  nextTick(() => {
    menuTreeRef.value!.setCheckedKeys(keys);
  });
};

const resetChecked = () => {
  menuTreeRef.value!.setCheckedKeys([]);
};

// 弹框打开和关闭
const handleClose = () => {
  resetChecked();
  form.value = cloneDeep(initForm);
  // 点击X关闭弹框时，需要更新visible
  emits("update:modelValue", false);
};
const handleOpen = () => {
  props.flag === "edit" && (form.value = cloneDeep(props.formData as EditForm)); // 更新表单数据
  props.formData?.menuIds && setCheckedKeys(props.formData.menuIds);
  formRef.value && formRef.value.clearValidate();
};

// 点击取消和确认按钮
const handleCancel = () => {
  emits("handleClose");
  // 点击取消按钮时，需要更新visible
  emits("update:modelValue", false);
};
const handleConfirm = (formEl: FormInstance) => {
  formEl.validate((valid) => {
    if (valid) {
      emits("handleConfirm", form.value);
      // 点击确认按钮时，需要在父组件api调用成功后更新visible，此处不做更新
    }
  });
};

const handleMenuChange = () => {
  form.value.menuIds = menuTreeRef.value!.getCheckedKeys() as number[];
  formRef.value!.validateField(["menuIds"]);
};
</script>

<style lang="scss" scoped>
.edit-add-form {
  width: 90%;
  margin: 0 auto;
}
</style>
